package logica.common;

import java.util.Vector;

import excepciones.DataStructureException;


public final class TagCollection {

	public enum commonTags { sec, tit, con };
	public enum linkTags { ira, vin, eti };
	public enum tagTipo { apertura, cierre, vacio, no_vacio };
	

	private Vector<Tag> tagCollection; 

	public TagCollection() 
	{
		this.tagCollection = new Vector();
		
		//Tags Common de apertura.
		for (commonTags cTags: commonTags.values()) 
		{ 	
			Vector <String> tagAntPermitidos = new Vector();
			
			switch (cTags)
			{
				case sec: tagAntPermitidos.addElement(tagTipo.vacio.toString()); tagAntPermitidos.addElement("</sec>"); tagAntPermitidos.addElement("<con>"); break;
				case tit: tagAntPermitidos.addElement(tagTipo.no_vacio.toString()); tagAntPermitidos.addElement("<sec>"); break;
				case con: tagAntPermitidos.addElement(tagTipo.no_vacio.toString()); tagAntPermitidos.addElement("</tit>"); break;
			}
			
			this.tagCollection.addElement(new Tag("<"+cTags+">", tagAntPermitidos, tagTipo.apertura)); 
		}
		
		//Tags de Cierre Commons
		for (commonTags cTags: commonTags.values()) 
		{ 	
			Vector <String> tagAntPermitidos = new Vector();
			
			switch (cTags)
			{
				case sec: tagAntPermitidos.addElement("</con>"); break;
				case tit: tagAntPermitidos.addElement("<tit>"); break;
				case con: tagAntPermitidos.addElement("<con>"); break;
			}
			
			this.tagCollection.addElement(new Tag("</"+cTags+">", tagAntPermitidos, tagTipo.cierre)); 
		}

		//Tags de Apertura Links
		for (linkTags cTags: linkTags.values()) 
		{ 	
			Vector <String> tagAntPermitidos = new Vector();
			
			switch (cTags)
			{
				case ira: tagAntPermitidos.addElement(tagTipo.no_vacio.toString()); tagAntPermitidos.addElement("</ira>"); tagAntPermitidos.addElement("<con>"); break;
				case vin: tagAntPermitidos.addElement(tagTipo.no_vacio.toString()); tagAntPermitidos.addElement("<ira>"); break;
				case eti: tagAntPermitidos.addElement(tagTipo.no_vacio.toString()); tagAntPermitidos.addElement("</vin>"); break;
			}
			
			this.tagCollection.addElement(new Tag("<"+cTags+">", tagAntPermitidos, tagTipo.apertura)); 
		}
		
		//Tags de Cierre Links
		for (linkTags cTags: linkTags.values()) 
		{ 	
			Vector <String> tagAntPermitidos = new Vector();
			
			switch (cTags)
			{
				case ira: tagAntPermitidos.addElement("</eti>"); break;
				case vin: tagAntPermitidos.addElement("<vin>"); break;
				case eti: tagAntPermitidos.addElement("<tit>"); break;
			}
			
			this.tagCollection.addElement(new Tag("</"+cTags+">", tagAntPermitidos, tagTipo.cierre)); 
		}
		
	}
	
	public boolean contains (String aTag)
	{
		boolean retorno = false;
		for(int i=0; !retorno && i<this.tagCollection.size(); i++)
		{
			retorno = this.tagCollection.elementAt(i).getTagName().equals(aTag);
		}
		
		return retorno;
	}
	
	public Tag oContains (String aTag)
	{
		Tag retorno = null;
		for(int i=0; (retorno==null && i<this.tagCollection.size()); i++)
		{
			if (this.tagCollection.elementAt(i).getTagName().equals(aTag))
			{
				retorno = this.tagCollection.elementAt(i);
			}
		}
		
		return retorno;
	}
	
	public boolean esTagApetura (String aTag)
	{
		boolean retorno = false;
		Tag oTag = this.oContains(aTag);
		
		if(oTag instanceof Tag)
		{
			retorno = oTag.esTagApertura();
		}
		
		return retorno;
	}
	
	public boolean esTagCierre (String aTag)
	{
		boolean retorno = false;
		Tag oTag = this.oContains(aTag);
		
		if(oTag instanceof Tag)
		{
			retorno = oTag.esTagCierre();
		}
		
		return retorno;
	}
	
	public boolean cumpleCondicion (String sTag, String sCondicion)
	{
		boolean retorno = false;
		
		Tag oTag = this.oContains(sTag);
		
		if (oTag instanceof Tag)
		{
			retorno = oTag.tagAnteriorPermitido(sCondicion);
		}
		
		return retorno;
	}
	
	public boolean tieneTagsApertura(String aText)
	{
		boolean contieneTag=false;
		for (int i=0; !contieneTag && i<this.tagCollection.size(); i++)
		{
			if (contieneTag = aText.contains(this.tagCollection.elementAt(i).getTagName()))
			{
				contieneTag = this.tagCollection.elementAt(i).esTagApertura();
			}
		}
		return contieneTag;
	}

	public boolean tieneTagsCierre(String aText)
	{
		boolean contieneTag=false;
		for (int i=0; !contieneTag && i<this.tagCollection.size(); i++)
		{
			if (contieneTag = aText.contains(this.tagCollection.elementAt(i).getTagName()))
			{
				contieneTag = this.tagCollection.elementAt(i).esTagApertura();
			}
		}
		return contieneTag;
	}

	public int tieneTagsSecciones(String aText) throws DataStructureException
	{
		String aTextCopy1 = " "+aText;
		String aTextCopy2 = " "+aText;
		int cantidadApertura = 0, cantidadCierre = 0;
		int index = 0;
		
		String seccionApertura = "<"+commonTags.sec.toString()+">";
		String seccionCierre = "</"+commonTags.sec.toString()+">";
		
		while((index = aTextCopy1.indexOf(seccionApertura)) != -1)
		{
			aTextCopy1 = aTextCopy1.substring(index+seccionApertura.length());
			cantidadApertura++;
		}
		
		index = 0;
		
		while((index = aTextCopy2.indexOf(seccionCierre)) != -1)
		{
			aTextCopy2 = aTextCopy2.substring(index+seccionCierre.length());
			cantidadCierre++;
		}
		
		if (cantidadApertura != cantidadCierre)
		{
			throw new DataStructureException("Cantidad de Tags de Secciones dispares");
		}
		
		return cantidadApertura;
	}

	public boolean esTagApeturaSeccion(String tag) {
		return tag.contains("<"+commonTags.sec.toString()+">");
	}

	public boolean esTagCierreSeccion(String tag) {
		return tag.contains("</"+commonTags.sec.toString()+">");
	}


}
